/*
 * Copyright 2008 Neil Bacon
 * Distributed under the terms of the Mozilla Public License version 1.1
 * or the GNU General Public License version 3.
 */

package nb.xadd.operator.impl;

import java.util.BitSet;

import nb.cache.CacheMap;
import nb.util.IntMap;
import nb.xadd.node.Node;
import nb.xadd.node.NodeFactory;
import nb.xadd.operator.BinaryOperator;
import nb.xadd.operator.OperatorFactory;
import nb.xadd.operator.UnaryOperator;
import nb.xadd.operator.impl.PieceWiseConstantApproximation.Type;

public class OperatorFactoryImpl implements OperatorFactory {

    private final NodeFactory nodeFactory;
    private final CacheMap<UnaryOperatorCacheKey, Node> unaryOperatorCache;

    private final BinaryOperator addition;
    private final BinaryOperator multiplication;
    private final BinaryOperator maximum;

    private final UnaryOperator sort;

    public OperatorFactoryImpl(NodeFactory nodeFactory, CacheMap<ApplyCacheKey, Node> applyCache, CacheMap<UnaryOperatorCacheKey, Node> unaryOperatorCache) {
        this.nodeFactory = nodeFactory;
        this.unaryOperatorCache = unaryOperatorCache;

        addition = new Addition(nodeFactory, applyCache);
        multiplication = new Multiplication(nodeFactory, applyCache);
        maximum = new BinaryMaximum(nodeFactory, applyCache);

        sort = new Sort(nodeFactory, this, unaryOperatorCache);
    }

    @Override
    public BinaryOperator getAddition() {
        return addition;
    }

    @Override
    public BinaryOperator getMultiplication() {
        return multiplication;
    }

    @Override
    public BinaryOperator getBinaryMaximum() {
        return maximum;
    }

    @Override
    public UnaryOperator getUnaryMaximum(BitSet booleanVarIndexSet, BitSet realVarIndexSet) {
        return new UnaryMaximum(nodeFactory, this, unaryOperatorCache, booleanVarIndexSet, realVarIndexSet);
    }

    @Override
    public UnaryOperator getNegation(BitSet booleanVarIndexSet, BitSet realVarIndexSet) {
        return new Negation(nodeFactory, unaryOperatorCache, booleanVarIndexSet, realVarIndexSet);
    }

    @Override
    public UnaryOperator getVariableSubstitution(IntMap booleanVarMap, IntMap realVarMap) {
        return new VariableSubstitution(nodeFactory, this, unaryOperatorCache, booleanVarMap, realVarMap);
    }

    @Override
    public UnaryOperator getIntegration(BitSet booleanVarIndexSet, BitSet realVarIndexSet) {
        return new Integration(nodeFactory, this, unaryOperatorCache, booleanVarIndexSet, realVarIndexSet);
    }

    @Override
    public UnaryOperator getPieceWiseConstantApproximation(Type type, double errorLimit, int pieceCountLimit) {
        return new PieceWiseConstantApproximation(nodeFactory, this, unaryOperatorCache, type, errorLimit, pieceCountLimit);
    }

    @Override
    public UnaryOperator getSort() {
        return sort;
    }

}
